﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YJKPatternSign.StairsRoomPlanSign.ModelLayer;

namespace YJKPatternSign.StairsRoomPlanSign.ControlLayer
{
	internal class ScissorStairDimensionPackerGeter : IStairsDimensionPackerGeter
	{
		public ScissorStairDimensionPackerGeter(SignUseStairsPacker inputPacker)
		{
			this.PrepareInformation(inputPacker);
		}

		public bool TryGetADimensionBean(SignUseStairsPacker useStairs, StairsDimensionKindEnum useKind, out List<IDimensionMake> outPutValue)
		{
			outPutValue = null;
			if (useStairs != this.m_useSairsPacker || this.m_useSairsPacker == null)
			{
				return false;
			}
			switch (useKind)
			{
			case StairsDimensionKindEnum.StairsWidth:
				outPutValue = this.m_lstStairWidthDimensionBean.Cast<IDimensionMake>().ToList<IDimensionMake>();
				break;
			case StairsDimensionKindEnum.StairsLength:
				outPutValue = this.m_lstStiarLengthDimensionBean.Cast<IDimensionMake>().ToList<IDimensionMake>();
				break;
			case StairsDimensionKindEnum.LevelDimension:
				outPutValue = (from n in this.m_lstLevelDimensionPacker
				where n != null
				select n).ToList<LevelDimensionPacker>().Cast<IDimensionMake>().ToList<IDimensionMake>();
				break;
			case StairsDimensionKindEnum.EvacuationRadius:
				outPutValue = this.m_lstEvacuationRadiusBean.Cast<IDimensionMake>().ToList<IDimensionMake>();
				break;
			case StairsDimensionKindEnum.PathDimensionBean:
				outPutValue = this.m_lstUsePathDImensionBean.Cast<IDimensionMake>().ToList<IDimensionMake>();
				break;
			}
			return true;
		}

		private void PrepareInformation(SignUseStairsPacker inputPacker)
		{
			this.m_useSairsPacker = inputPacker;
			this.m_thisStairsCondition = inputPacker.ThisStairsCondition;
			this.PrepareRuns();
			if (this.m_bIfGetInformationRight)
			{
				this.PrePareFlatRoof();
			}
			if (this.m_bIfGetInformationRight)
			{
				this.AddWallInformationToStairsRuns();
			}
			if (this.m_bIfGetInformationRight)
			{
				this.MakeDimensionBean();
			}
		}

		private void MakeDimensionBean()
		{
			this.MakeAllLevelDimension();
			this.MakeAllStairsWidthDimension();
			this.MakeAllStairsRunsDimension();
			this.MakeAllPath();
			this.MakeAllEvacuationRadiusDimension();
		}

		private void MakeAllPath()
		{
			int item = 1;
			switch (this.m_thisStairsCondition)
			{
			case StairConditionEnum.Down:
				item = 1;
				break;
			case StairConditionEnum.Normal:
				item = 1;
				break;
			case StairConditionEnum.Top:
				item = 2;
				break;
			}
			if (this.m_lstThisStairsRunPacker != null)
			{
				for (int i = 0; i < 2; i++)
				{
					Line stairRunMidLine = this.m_lstThisStairsRunPacker[i].GetStairRunMidLine(true);
					XYZ item2 = stairRunMidLine.GetEndPoint(1).Add(-stairRunMidLine.Direction.Normalize() * stairRunMidLine.Length * 0.1);
					PathDimensionBean item3 = new PathDimensionBean(new List<XYZ>
					{
						stairRunMidLine.GetEndPoint(0),
						item2
					}, new List<int>
					{
						3,
						item
					});
					this.m_lstUsePathDImensionBean.Add(item3);
				}
			}
			if (this.m_lstDownStairsRunPacker.Count != 0 && this.m_thisStairsCondition == StairConditionEnum.Normal)
			{
				foreach (StairsRunPacker stairsRunPacker in this.m_lstDownStairsRunPacker)
				{
					if (stairsRunPacker.ViewKind == ShapeViewKindEnum.Cut)
					{
						Line stairRunMidLine2 = stairsRunPacker.GetStairRunMidLine(true);
						PathDimensionBean item4 = new PathDimensionBean(new List<XYZ>
						{
							stairRunMidLine2.GetEndPoint(1),
							stairRunMidLine2.GetEndPoint(0).Add(stairRunMidLine2.Direction.Normalize() * stairRunMidLine2.Length * 0.1)
						}, new List<int>
						{
							3,
							2
						});
						this.m_lstUsePathDImensionBean.Add(item4);
					}
				}
			}
		}

		private void MakeAllLevelDimension()
		{
			using (List<FlatRoofPacker>.Enumerator enumerator = this.m_lstAllFlatRoof.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					LevelDimensionPacker item;
					if (enumerator.Current.TryGetALevelDimension(out item))
					{
						this.m_lstLevelDimensionPacker.Add(item);
					}
				}
			}
		}

		private void MakeAllStairsWidthDimension()
		{
			for (int i = 0; i < 2; i++)
			{
				Line inputLine = this.m_lstThisStairsRunPacker[0].GetStairRunEndCurve(i, false) as Line;
				DimensionInformensionBean item;
				if (this.m_StairsWellUnit.TryGetDimensionInformensionByLine(inputLine, out item, false, true, true))
				{
					this.m_lstStairWidthDimensionBean.Add(item);
				}
			}
		}

		private void MakeAllStairsRunsDimension()
		{
			bool flag = true;
			List<int> list = new List<int>();
			for (int i = 0; i < this.m_lstAllStairsRunPacker.Count - 1; i++)
			{
				flag = (flag && this.m_lstAllStairsRunPacker[i].GetRunShapeDesText(false).Equals(this.m_lstAllStairsRunPacker[i + 1].GetRunShapeDesText(false)));
				flag = (flag && this.IfTwoStairsRunsLocationNear(this.m_lstAllStairsRunPacker[i], this.m_lstAllStairsRunPacker[i + 1]));
			}
			if (this.m_thisStairsCondition == StairConditionEnum.Normal)
			{
				for (int j = 0; j < 2; j++)
				{
					if (this.m_lstThisStairsRunPacker[j].ThisStairsRun.GetStairs().ActualTreadDepth != this.m_lstDownStairsRunPacker[j].ThisStairsRun.GetStairs().ActualTreadDepth)
					{
						list.Add(j);
					}
				}
			}
			this.m_lstStiarLengthDimensionBean.AddRange(this.MakeAStairsLengthDimension(this.m_lstThisStairsRunPacker[0], true));
			if (!flag)
			{
				this.m_lstStiarLengthDimensionBean.AddRange(this.MakeAStairsLengthDimensionByFlate(new List<StairsRunPacker>
				{
					this.m_lstThisStairsRunPacker[1]
				}, !list.Contains(1)));
				foreach (int index in list)
				{
					Line line = this.m_lstThisStairsRunPacker[index].GetStairRunMidLine(true);
					line = Utility.MoveALineAtVerticalDirection(line, -1.5 * StaticResource.MoveDistanceOfCut, false);
					this.MakeACutDimension(line, this.m_lstThisStairsRunPacker[index]);
					this.MakeACutDimension(line, this.m_lstDownStairsRunPacker[index]);
				}
			}
		}

		private void MakeAllEvacuationRadiusDimension()
		{
			if (this.m_StairsWellUnit != null && !this.m_StairsWellUnit.TryGetEvacuationRadiusInformation(out this.m_lstEvacuationRadiusBean))
			{
				this.m_lstEvacuationRadiusBean = new List<EvacuationRadiusInformationBean>();
			}
		}

		private bool IfTwoStairsRunsLocationNear(StairsRunPacker inputRunOne, StairsRunPacker inputRunTwo)
		{
			bool result = false;
			Curve curve = inputRunOne.GetStairRunMidLine(false);
			curve = curve.Clone();
			curve.MakeUnbound();
			XYZ xyzpoint = curve.Project(inputRunOne.GetStairRunMidLine(false).GetEndPoint(0)).XYZPoint;
			Curve stairRunMidLine = inputRunTwo.GetStairRunMidLine(false);
			for (int i = 0; i < 2; i++)
			{
				if (curve.Project(stairRunMidLine.GetEndPoint(i)).XYZPoint.IsAlmostEqualTo(xyzpoint))
				{
					result = true;
				}
			}
			return result;
		}

		private void MakeACutDimension(Line useCutDimensionLine, StairsRunPacker useRunPacker)
		{
			DimensionInformensionBean dimensionInformensionBean = null;
			if (useRunPacker.TryGetDimensionInformensionByLine(useCutDimensionLine, out dimensionInformensionBean, true, false, false))
			{
				dimensionInformensionBean.LstReplacedText = new List<string>
				{
					useRunPacker.GetRunShapeDesText(false)
				};
				this.m_lstStiarLengthDimensionBean.Add(dimensionInformensionBean);
			}
		}

		private List<DimensionInformensionBean> MakeAStairsLengthDimension(StairsRunPacker inputRun = null, bool ifChangeText = false)
		{
			List<DimensionInformensionBean> list = new List<DimensionInformensionBean>();
			StairsRunPacker stairsRunPacker = null;
			DimensionInformensionBean dimensionInformensionBean = null;
			if (inputRun != null)
			{
				stairsRunPacker = inputRun;
			}
			Line line = stairsRunPacker.GetStairRunMidLine(false);
			line = Utility.MoveALineAtVerticalDirection(line, StaticResource.MoveDistanceOfStairsLegth, false);
			if (stairsRunPacker.TryGetDimensionInformensionByLine(line, out dimensionInformensionBean, false, false, false))
			{
				if (ifChangeText)
				{
					dimensionInformensionBean.LstReplacedText = new List<string>
					{
						stairsRunPacker.GetRunShapeDesText(false)
					};
				}
				list.Add(dimensionInformensionBean);
			}
			using (List<FlatRoofPacker>.Enumerator enumerator = this.m_lstAllFlatRoof.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					if (enumerator.Current.TryGetDimensionInformensionByLine(line, out dimensionInformensionBean, false, false, false))
					{
						list.Add(dimensionInformensionBean);
					}
				}
			}
			return list;
		}

		private List<DimensionInformensionBean> MakeAStairsLengthDimensionByFlate(List<StairsRunPacker> inputLstStairsRunPacker, bool ifChangeText)
		{
			List<DimensionInformensionBean> list = new List<DimensionInformensionBean>();
			DimensionInformensionBean item = null;
			string item2 = null;
			if (inputLstStairsRunPacker != null && inputLstStairsRunPacker.Count != 0)
			{
				item2 = inputLstStairsRunPacker[0].GetRunShapeDesText(false);
			}
			Line line = inputLstStairsRunPacker[0].GetStairRunMidLine(false);
			line = Utility.MoveALineAtVerticalDirection(line, StaticResource.MoveDistanceOfStairsLegth, false);
			using (List<FlatRoofPacker>.Enumerator enumerator = this.m_lstAllFlatRoof.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					if (enumerator.Current.TryGetDimensionInformensionByLine(line, out item, false, false, false))
					{
						list.Add(item);
					}
				}
			}
			if (list.Count >= 2)
			{
				list[0].LstDimensionPoints.AddRange(list[1].LstDimensionPoints);
				list = new List<DimensionInformensionBean>
				{
					list[0]
				};
				if (ifChangeText)
				{
					list[0].LstReplacedText = new List<string>
					{
						null,
						item2,
						null
					};
				}
			}
			return list;
		}

		private void AddWallInformationToStairsRuns()
		{
			new List<StairsRunPacker>();
			int inputIndex = 0;
			foreach (StairsRunPacker stairsRunPacker in this.m_lstThisStairsRunPacker)
			{
				Line line = stairsRunPacker.GetStairRunEndCurve(inputIndex, false) as Line;
				XYZ inputPoint = line.Evaluate(0.5, true);
				for (int i = -1; i < 2; i += 2)
				{
					Curve input;
					if (StairsDimensionUtilityMethod.TryFindABoundaryByPointAndDriection(inputPoint, (double)i * line.Direction, this.m_lstWallCurves, out input))
					{
						stairsRunPacker.AddACurveToShape(input);
					}
				}
			}
		}

		private void PrePareFlatRoof()
		{
			this.m_lstAllFlatRoof = new List<FlatRoofPacker>
			{
				null,
				null
			};
			StairPlanDataPacker useStairPlanData = this.m_useSairsPacker.UseStairPlanData;
			foreach (WallElementPacker wallElementPacker in useStairPlanData.LstAllWallElementPacker)
			{
				foreach (Curve item in wallElementPacker.LstOffestCurve)
				{
					this.m_lstWallCurves.Add(item);
				}
			}
			foreach (ColumnPacker columnPacker in useStairPlanData.LstColumnPackers)
			{
				this.m_lstWallCurves.AddRange(columnPacker.LstBoundCurves);
			}
			this.m_lstWallCurves = Utility.ChangeLstCurveZ(this.m_lstWallCurves, SignManger.ThisStairPlandDataPacker.NowViewZ);
			switch (this.m_thisStairsCondition)
			{
			case StairConditionEnum.Down:
				this.m_bIfGetInformationRight = (this.m_bIfGetInformationRight && this.m_lstDownStairsRunPacker.Count == 0 && this.m_lstThisStairsRunPacker.Count == 2);
				this.SetAllFlatRoofByRuns(false);
				break;
			case StairConditionEnum.Normal:
				this.m_bIfGetInformationRight = (this.m_bIfGetInformationRight && 2 == this.m_lstThisStairsRunPacker.Count && 2 == this.m_lstDownStairsRunPacker.Count);
				this.SetAllFlatRoofByRuns(false);
				break;
			case StairConditionEnum.Top:
				this.m_bIfGetInformationRight = (this.m_bIfGetInformationRight && this.m_lstThisStairsRunPacker.Count == 2);
				this.m_lstDownStairsRunPacker = new List<StairsRunPacker>();
				this.m_lstDownStairsRunPacker.AddRange(this.m_lstThisStairsRunPacker);
				this.SetAllFlatRoofByRuns(true);
				break;
			case StairConditionEnum.Error:
				this.m_bIfGetInformationRight = false;
				break;
			}
			if (this.m_bIfGetInformationRight && this.m_lstThisStairsRunPacker != null)
			{
				this.m_StairsWellUnit = new StairsWellUnitPacker(this.m_lstThisStairsRunPacker[0].ThisStairsRun.GetStairs(), this.m_lstThisStairsRunPacker[0], this.m_lstThisStairsRunPacker[1]);
			}
		}

		private void SetAllFlatRoofByRuns(bool ifUseEnd)
		{
			FlatRoofPacker value = null;
			if (this.TryCreatAFlatRootPackerByRun(this.m_lstThisStairsRunPacker[0], this.m_lstThisStairsRunPacker[1], ifUseEnd, out value))
			{
				this.m_lstAllFlatRoof[0] = value;
			}
			else
			{
				this.m_bIfGetInformationRight = false;
			}
			if (this.TryCreatAFlatRootPackerByRun(this.m_lstThisStairsRunPacker[1], this.m_lstThisStairsRunPacker[0], ifUseEnd, out value))
			{
				this.m_lstAllFlatRoof[1] = value;
				return;
			}
			this.m_bIfGetInformationRight = false;
		}

		private void PrepareRuns()
		{
			List<StairsRunPacker> list = this.m_useSairsPacker.LstAllStiarsRunPacker;
			this.m_lstAllStairsRunPacker.AddRange(this.m_useSairsPacker.LstAllStiarsRunPacker);
			list = (from n in list
			where n.ViewKind > ShapeViewKindEnum.None
			select n).ToList<StairsRunPacker>();
			list = (from k in list
			orderby -k.EndElevation
			select k).ToList<StairsRunPacker>();
			if (list.Count > 1)
			{
				this.m_lstThisStairsRunPacker.Add(list[0]);
				this.m_lstThisStairsRunPacker.Add(list[1]);
			}
			if (list.Count > 3)
			{
				for (int i = 0; i < 2; i++)
				{
					for (int j = 2; j < list.Count; j++)
					{
						if (list[i].IfShadowInputStairs(list[j]))
						{
							this.m_lstDownStairsRunPacker.Add(list[j]);
							double num = -this.m_useSairsPacker.UseViewData.CutHeightZ + this.m_lstThisStairsRunPacker[i].EndElevation;
							num = list[j].EndElevation - num;
							list[j].UpdataViewKindByInput(num, false);
							break;
						}
					}
				}
			}
			switch (this.m_thisStairsCondition)
			{
			case StairConditionEnum.Down:
				this.m_bIfGetInformationRight = (this.m_bIfGetInformationRight && this.m_lstDownStairsRunPacker.Count == 0 && this.m_lstThisStairsRunPacker.Count == 2);
				return;
			case StairConditionEnum.Normal:
				this.m_bIfGetInformationRight = (this.m_bIfGetInformationRight && 2 == this.m_lstThisStairsRunPacker.Count && 2 == this.m_lstDownStairsRunPacker.Count);
				return;
			case StairConditionEnum.Top:
				this.m_bIfGetInformationRight = (this.m_bIfGetInformationRight && this.m_lstThisStairsRunPacker.Count == 2);
				this.m_lstDownStairsRunPacker = new List<StairsRunPacker>();
				this.m_lstDownStairsRunPacker.AddRange(this.m_lstThisStairsRunPacker);
				return;
			case StairConditionEnum.Error:
				this.m_bIfGetInformationRight = false;
				return;
			default:
				return;
			}
		}

		private bool TryCreatAFlatRootPackerByRun(StairsRunPacker inputPackerOne, StairsRunPacker inputPackerTwo, bool ifUseEndElvation, out FlatRoofPacker createdValue)
		{
			createdValue = null;
			bool result = true;
			List<Curve> list = new List<Curve>();
			double inputElevation = Math.Min(inputPackerOne.StartElevation, inputPackerTwo.StartElevation);
			if (ifUseEndElvation)
			{
				inputElevation = Math.Max(inputPackerOne.EndElevation, inputPackerTwo.EndElevation);
			}
			Curve stairRunEndCurve = inputPackerOne.GetStairRunEndCurve(0, false);
			Curve stairRunEndCurve2 = inputPackerTwo.GetStairRunEndCurve(1, false);
			list.Add(stairRunEndCurve);
			list.Add(stairRunEndCurve2);
			XYZ direction = inputPackerOne.GetStairRunMidLine(true).Direction;
			XYZ direction2 = inputPackerTwo.GetStairRunMidLine(true).Direction;
			Curve curve;
			StairsDimensionUtilityMethod.TryFindANearBoundaryByStairsRun(inputPackerOne, 0, this.m_lstWallCurves, out curve);
			Curve curve2;
			StairsDimensionUtilityMethod.TryFindANearBoundaryByStairsRun(inputPackerTwo, 1, this.m_lstWallCurves, out curve2);
			if (null != curve)
			{
				list.Add(curve);
			}
			if (null != curve2)
			{
				list.Add(curve2);
			}
			createdValue = new FlatRoofPacker(inputElevation, null, list, new List<StairsRunPacker>
			{
				inputPackerOne,
				inputPackerTwo
			});
			return result;
		}

		private SignUseStairsPacker m_useSairsPacker;

		private StairConditionEnum m_thisStairsCondition = StairConditionEnum.Error;

		private List<StairsRunPacker> m_lstAllStairsRunPacker = new List<StairsRunPacker>();

		private List<StairsRunPacker> m_lstThisStairsRunPacker = new List<StairsRunPacker>();

		private List<StairsRunPacker> m_lstDownStairsRunPacker = new List<StairsRunPacker>();

		private List<FlatRoofPacker> m_lstAllFlatRoof = new List<FlatRoofPacker>();

		private StairsWellUnitPacker m_StairsWellUnit;

		private List<Line> m_lstLine = new List<Line>();

		private bool m_bIfGetInformationRight = true;

		private List<LevelDimensionPacker> m_lstLevelDimensionPacker = new List<LevelDimensionPacker>();

		private List<DimensionInformensionBean> m_lstStairWidthDimensionBean = new List<DimensionInformensionBean>();

		private List<DimensionInformensionBean> m_lstStiarLengthDimensionBean = new List<DimensionInformensionBean>();

		private List<PathDimensionBean> m_lstUsePathDImensionBean = new List<PathDimensionBean>();

		private List<EvacuationRadiusInformationBean> m_lstEvacuationRadiusBean = new List<EvacuationRadiusInformationBean>();

		private List<Curve> m_lstWallCurves = new List<Curve>();
	}
}
